package com.yhos.platform.oopston.core.json;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Spring Boot 2.0使用的是Spring5.0,Spring5.0中WebMvcConfigurerAdapter算过时的，不再建议使用，
 * 那么我们可以使用WebMvcConfigurationSupport来代替。
 */
@Configuration
public class JsonConfig {

    /**
     * 用于常规请求的FastJson Convert
     *
     * @return
     */
    @Bean
    public CustomizedFastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
        CustomizedFastJsonHttpMessageConverter converter = new CustomizedFastJsonHttpMessageConverter();

        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteNonStringValueAsString,
                SerializerFeature.WriteNonStringKeyAsString,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.WriteNullListAsEmpty
        );

        config.setSerializeFilters((ValueFilter) (object, name, value) -> {
            Class type = getFileClassType(object, name);
            if (value == null) {
                if (BigDecimal.class == type || Integer.class == type || Date.class == type
                        || String.class == type || Long.class == type || Byte.class == type) {
                    return "";
                }
            } else {
                if (Date.class == type) {
                    return String.valueOf(((Date) value).getTime());
                }
            }
            return value;
        });

        converter.setSupportedMediaTypes(fastMediaTypes);
        converter.setFastJsonConfig(config);
        return converter;
    }

    /**
     * 用于Feign请求的FastJson Convert
     *
     * @return
     */
    @Bean
    public CustomizedFastJsonHttpMessageConverter fastJsonHttpMessageConverterForFeign() {
        CustomizedFastJsonHttpMessageConverter converter = new CustomizedFastJsonHttpMessageConverter();

        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_PROBLEM_JSON_UTF8);
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteNonStringValueAsString,
                SerializerFeature.WriteNonStringKeyAsString,
                SerializerFeature.WriteNullListAsEmpty
        );

        config.setSerializeFilters((ValueFilter) (object, name, value) -> {
            Class type = getFileClassType(object, name);
            if (value == null) {
                return value;
            } else {
                if (Date.class == type) {
                    return String.valueOf(((Date) value).getTime());
                }
            }
            return value;
        });

        converter.setSupportedMediaTypes(fastMediaTypes);
        converter.setFastJsonConfig(config);
        return converter;
    }

    private Class getFileClassType(Object object, String name) {
        Class type;
        try {
            type = object.getClass().getDeclaredField(name).getType();
        } catch (NoSuchFieldException e) {
            try {
                type = object.getClass().getSuperclass().getDeclaredField(name).getType();
            } catch (NoSuchFieldException ex) {
                type = null;
            }
        }
        return type;
    }

}
